﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Xml;
using System.Xml.Linq;


namespace crmbl.Azure.Subscription.Processor
{


    public class HostedService
    {
        public String ServiceName;
        public String Description;
        public String AffinityGroup;
        public String Location;
        public String Label;
        public String Status;
        public DateTime DateCreatedUTC;
        public DateTime DateModifiedUTC;

        public Deployment[] Deployments;
    }

    public class Deployment
    {
        public String Name;
        public String DeploymentSlot;
        public Guid PrivateId;
        public String Status;
        public String Label;
        public String URL;
    }

    public class SubscriptionProcessor : IDisposable
    {

        private Guid _SubscriptionId;
        private String _CertificateSubjectName;
        private X509Certificate2 _ManagementCertificate;

        private String _ApiVersion = "2011-10-01";

        public SubscriptionProcessor(Guid subscriptionId, String certificateSubjectName)
        {

            // Assign Class Level
            _SubscriptionId = subscriptionId;
            _CertificateSubjectName = certificateSubjectName;
            _ManagementCertificate = GetCertificateBySubjectName(_CertificateSubjectName);



        }

        public List<object> ListHostedServices()
        {
            return RunAPIQuery("services/hostedservices");
        }

        private XDocument RunAPIQuery(String requestGetString)
        {
            string uriFormat = "https://management.core.windows.net/{0}/" + requestGetString;

            Uri uri = new Uri(String.Format(uriFormat, _SubscriptionId));

            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
            request.Method = "GET";
            request.Headers.Add("x-ms-version", _ApiVersion);
            request.ClientCertificates.Add(_ManagementCertificate);
            request.ContentType = "application/xml";

            XDocument responseBody = null;
            HttpStatusCode statusCode;
            HttpWebResponse response;
            try
            {
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException ex)
            {
                // GetResponse throws a WebException for 400 and 500 status codes
                response = (HttpWebResponse)ex.Response;
            }

            //statusCode = response.StatusCode;

            if (response.ContentLength > 0)
            {
                using (XmlReader reader = XmlReader.Create(response.GetResponseStream()))
                {
                    responseBody = XDocument.Load(reader);
                }
            }

            response.Close();

            return responseBody;

            /*
            if (statusCode.Equals(HttpStatusCode.OK))
            {
                
                XNamespace wa = "http://schemas.microsoft.com/windowsazure";
                XElement hostedServices = responseBody.Element(wa + "HostedServices");
                Console.WriteLine(
                    "Hosted Services for Subscription ID {0}:{1}{2}",
                    subscriptionId,
                    Environment.NewLine,
                    hostedServices.ToString(SaveOptions.OmitDuplicateNamespaces));
            }
            else
            {
                Console.WriteLine("Call to List Hosted Services returned an error:");
                Console.WriteLine("Status Code: {0} ({1}):{2}{3}",
                    (int)statusCode, statusCode, Environment.NewLine,
                    responseBody.ToString(SaveOptions.OmitDuplicateNamespaces));
            }
            return;
             * */
        }


        #region Private 

        private X509Certificate2 GetCertificateBySubjectName(String subjectName)
        {
            List<StoreLocation> locations = new List<StoreLocation> 
            { 
                StoreLocation.CurrentUser, 
                StoreLocation.LocalMachine 
            };

            foreach (var location in locations)
            {
                X509Store store = new X509Store("My", location);
                try
                {
                    store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                    X509Certificate2Collection certificates = store.Certificates.Find(X509FindType.FindBySubjectName, subjectName, false);

                    if (certificates.Count == 1)
                    {
                        return certificates[0];
                    }
                }
                finally
                {
                    store.Close();
                }
            }

            throw new ArgumentException(string.Format("A Certificate with SubjectName '{0}' could not be found in local computer and user stores.",subjectName));
        }

        #endregion

        public void Dispose()
        {
            throw new NotImplementedException();
        }
    }
}
